#include <iostream>
#include "Socket.hpp"
#include "Protocol.hpp"
#include <ctime>
const std::string opers = "+-*/=^&";
using namespace Protocol;
int main(int argc, char *argv[])
{
    srand(time(0));
    if (argc != 3)
    {
        std::cout << "Usage: " << argv[0] << " serverip serverport" << std::endl;
        return 1;
    }
    std::string serverip = argv[1];
    uint16_t serverport = std::stoi(argv[2]);
    Net_Work::Socket *conn = new Net_Work::TcpSocket();
    bool ret = conn->BuildConnectSocketMethod(serverip, serverport);
    if (!ret)
    {
        std::cout << "connect " << serverip << ":" << serverport << " fail" << std::endl;
        return 2;
    }
    std::cout << "connect " << serverip << ":" << serverport << " success" << std::endl;
    std::shared_ptr<Factory> factory = std::make_shared<Factory>();

    while (true)
    {
        int x = rand() % 100;
        usleep(1000);
        int y = rand() % 100;
        char oper = opers[rand() % opers.size()];
        std::shared_ptr<Request> req = factory->BuildRequest(x, y, oper);

        // 1.先进行序列化处理
        std::string requeststr;
        req->Serializate(&requeststr);

        // for test
        std::string testreq;
        testreq += requeststr;
        testreq += " = ";

        // 2.将序列化的字符串进行编码
        std::string send_string;
        send_string = Encode(requeststr);

        // 3.将该字符串发送给服务器
        conn->Send(send_string);

        std::string responsestr;
        while (true)
        {
            // 4.读取来自服务器的消息，如："len\nresult code\n"
            if (!conn->Recv(&responsestr, 1024))
                break;

            // 5.将来自服务器的消息进行解码
            std::string response;
            if (!Decode(responsestr, &response))
                continue;

            // 6.将解码出来的消息进行反序列化
            std::shared_ptr<Response> resp = factory->BuildResponse();
            if (!resp->Deserialize(response))
                break;

            // 7. 得到了计算结果，而且是一个结构化的数据
            std::cout << testreq << resp->GetResult() << "[" << resp->GetCodeString(resp->GetCode()) << "]" << std::endl;
            break;
        }
        sleep(1);
    }
    conn->CloseSocket();

    return 0;
}